iT邦幫忙

2022 iThome 鐵人賽

DAY 22
2
Modern Web

今天我想來在 Angular 應用程式上加上測試保護系列 第 22

Day 22 - 端對端測試 - 使用 Fixture 定義測試資料與環境變數設定

  • 分享至 

  • xImage
  •  

前言

前幾天我們說明了如何利用 Cypress 來撰寫端對端測試程式。這一篇來說明如何在 Cypress 設定環境變數,以及利用 Cypress 所提供的 fixture 來組織測試案例所需要的資料。

Cypress 環境變數

先前的登入頁面測試程式中,我們在 before()after() 生命週期方法,透過 JSON Server 的 API 新增與移除測試的初始資料。這一篇就來說明,如何把其中的 API 路徑設定在 Cypress 的環境變數中,讓所有測試檔案可以使用。

describe('使用者登入', () => {
  before(() => {
    cy.request('POST', 'http://localhost:3000/users', {
      id: 'userA',
      password: '1234567',
    });
  });

  after(() => {
    cy.request('DELETE', 'http://localhost:3000/users/userA');
  });
});

在 Cypress 中,可以把需要的環境變數設定在組態檔案內。因此,我們在 cypress.config.ts 檔案中的 env 屬性加入 apiUrl 來定義後端服務的路徑。

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:4200',
    supportFile: false,
    env: {
      apiUrl: 'http://localhost:3000',
    },
  },
});

除非之外,也可以新增 cypress.env.json 檔案來專職記錄 Cypress 環境變數。

{
  "apiUrl": "http://localhost:3000"
}

也可以在 Cypress 的 CLI 命令加上 --env 參數來指定環境變數。

cypress run --env apiUrl=http://localhost:3000

而在使用上會使用 Cypress.env() 方法來取得所需要的環境變數。因此,我們可以修改 login.cy.ts 檔案,利用 apiUrl 環境變數來處理初始資料。

before(() => {
  cy.request('POST', `${Cypress.env('apiUrl')}/users`, {
    id: 'userA',
    password: '1234567',
  });
});

after(() => {
  cy.request('DELETE', `${Cypress.env('apiUrl')}/users/userA`);
});

使用 fixture() 取得測試資料

在使用者登入的測試案例中,我們分別會用三種不同的測試資料來測試帳號不存在、登入成功與失敗等案例。

describe('登入作業', () => {
  it('當輸入不存在帳號, 應顯示錯誤訊息, 且無法按下登入按鈕', () => {
    cy.get('button.mat-icon-button').contains('login').click();
    cy.get('input[type=text]').type('userB').blur();
    cy.get('mat-error').should('exist').and('have.text', '此帳號不存在');
    cy.get('button').contains('登入').parent().should('be.disabled');
  });

  it('當輸入錯誤帳號密碼, 應登入失敗', () => {
    cy.get('button.mat-icon-button').contains('login').click();
    cy.get('input[type=text]').type('userA');
    cy.get('input[type=password]').type('00000');
    cy.get('button').contains('登入').parent().click({ force: true }).should('not.be.disabled');
    cy.get('.mat-snack-bar-container').should('exist').and('have.text', '登入失敗');
  });

  it('當輸入正確帳號密碼, 應登入成功', () => {
    cy.get('button.mat-icon-button').contains('login').click();
    cy.get('input[type=text]').type('userA');
    cy.get('input[type=password]').type('1234567');
    cy.get('button').contains('登入').parent().click({ force: true }).should('not.be.disabled');
    cy.get('.mat-snack-bar-container').should('exist').and('have.text', '登入成功');
  });
}); 

然而,在 cypress 資料夾下存在著 fixture 資料,是用來放測試案例所需要用到的資料。因此我們可以這個資料夾下新增 users 目錄,並加入帳號不存在 (id-not-exist.json)、登入成功 (login-success.json) 與失敗 (login-failed.json) 三個案例所需要的 json 檔。

{
  "id": "userA",
  "password": "1234567"
}

上面的 JSON 是針對使用者登入成功的案例所需要的測試資料,此時就可以在測試程式中利用 fixture() 方法來取得。如下面程式,fixture() 方法會傳入測試資料所在的路徑,Cypress 會去 cypress\fixture 資料夾內,依 jsonjscoffeehtmltxtcsv 等順序去找尋並取得測試資料。由於在 Cypress 內的方法都是非同步處理,因此我們會利用 then() 方法來取得的使用者資料並進行測試。

it('當輸入正確帳號密碼, 應登入成功', () => {
  cy.fixture('users/login-success').then(({ id, password }) => {
    cy.get('button.mat-icon-button').contains('login').click();
    cy.get('input[type=text]').type(id);
    cy.get('input[type=password]').type(password);
    cy.get('button').contains('登入').parent().click({ force: true }).should('not.be.disabled');
    cy.get('.mat-snack-bar-container').should('exist').and('have.text', '登入成功');
  });
});

接下來

今天利用 Cypress 環境變數設定資料庫設定所需的路徑,也使用 Cypress 所提供的 fixture() 來整理測試案例所需要的測試資料,完整的測試程式可以參考 GitHub。由於端對點測試是從使用者操作的角度去撰寫,因而在測試程式中會重覆地使用取得頁面元素的程式。接下來,會說明如何利用 Cypress 的別名與自訂命令來降低程式碼的重覆。


上一篇
Day 21 - 端對端測試 - 利用 Cypress 驗證應用程式
下一篇
Day 23 - 端對端測試 - Cypress 別名與自訂命令
系列文
今天我想來在 Angular 應用程式上加上測試保護30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言